package com.laiketui.plugin.common.service.user;

import com.alibaba.fastjson.JSON;
import com.laiketui.core.cache.RedisUtil;
import com.laiketui.core.exception.LaiKeAPIException;
import com.laiketui.core.lktconst.GloabConst;
import com.laiketui.plugin.common.domain.base.RecordModel;
import com.laiketui.plugin.common.domain.base.SignRecordModel;
import com.laiketui.plugin.common.domain.base.User;
import com.laiketui.plugin.common.domain.lktconst.ErrorCode;
import com.laiketui.plugin.common.domain.vo.integral.AddScoreVo;
import com.laiketui.plugin.common.interfaces.PublicIntegralService;
import com.laiketui.plugin.common.interfaces.user.PublicUserService;
import com.laiketui.plugin.common.mapper.RecordModelMapper;
import com.laiketui.plugin.common.mapper.UserBaseMapper;
import com.laiketui.plugin.common.tool.cache.RedisDataTool;
import com.laiketui.plugin.common.tool.str.StringUtils;
import com.laiketui.root.license.Md5Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;

/**
 * 会员公共接口
 *
 * @author Trick
 * @date 2020/12/23 10:26
 */
@Service
public class PublicUserServiceImpl implements PublicUserService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private PublicIntegralService publicIntegralService;

    @Override
    public boolean balancePay(String accessId, BigDecimal payPrice, String text, int type) throws LaiKeAPIException {
        try {
            User userCache = RedisDataTool.getRedisUserCache(accessId, redisUtil, true);
            int count = userBaseMapper.rechargeUserPrice(userCache.getId(), payPrice.negate());
            if (count < 1) {
                logger.info("余额支付失败");
                return false;
            }
            //记录一笔记录
            RecordModel recordModel = new RecordModel(userCache.getStore_id(), userCache.getUser_id(), payPrice, userCache.getMoney(), new Date(), text, type);
            if (recordModelMapper.insertSelective(recordModel) < 1) {
                logger.info("余额支付失败 -金额记录失败 参数{}", JSON.toJSONString(recordModel));
                return false;
            }
            //刷新用户信息
            User userInfo = new User();
            userInfo.setId(userCache.getId());
            userInfo = userBaseMapper.selectOne(userInfo);
            RedisDataTool.refreshRedisUserCache(accessId, userInfo, redisUtil);
        } catch (LaiKeAPIException l) {
            throw l;
        } catch (Exception e) {
            logger.error("余额支付 异常", e);
            throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_WLYC, "网络异常", "balancePay");
        }
        return true;
    }


    @Override
    public void validatePayPwd(String userId, String pwd) throws LaiKeAPIException {
        try {
            if (StringUtils.isEmpty(userId)) {
                throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_CSCW, "参数错误");
            }
            if (StringUtils.isEmpty(pwd)) {
                throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_QSRZFMM, "请输入支付密码");
            }
            User user = new User();
            user.setUser_id(userId);
            user = userBaseMapper.selectOne(user);
            //重试次数
            Integer validateNum = user.getLogin_num();
            if (validateNum.equals(GloabConst.LktConfig.PASSWORD_VALIDATE_NUM)) {
                throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_YBSDQMTZS, "已被锁定,请明天再试", "paymentPassword");
            }
            if (StringUtils.isEmpty(user.getPassword())) {
                throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_WSZZFMM, "未设置支付密码");
            }
            User userParam = new User();
            userParam.setId(user.getId());
            pwd = Md5Util.MD5endoce(pwd);
            if (user.getPassword().equals(pwd)) {
                //验证成功
                userParam.setLogin_num(0);
                int count = userBaseMapper.updateByPrimaryKeySelective(userParam);
                if (count < 0) {
                    logger.info("用户 id = " + user.getId() + " 支付密码验证通过,login_num 未清空");
                }
            } else {
                userParam.setLogin_num(++validateNum);
                userBaseMapper.updateUserInfoById(userParam);
                logger.info("用户 id = " + user.getId() + " 正在重试支付密码 当前次数 " + userParam.getLogin_num());
                throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_ZFMMBZQ, "支付密码不正确");
            }
        } catch (LaiKeAPIException l) {
            throw l;
        } catch (Exception e) {
            logger.error("验证支付密码 异常", e);
            throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_WLYC, "网络异常", "validatePayPwd");
        }
    }


    @Override
    public boolean userRechargeMoney(int storeId, int id, BigDecimal money, int type) throws LaiKeAPIException {
        try {
            int count;
            //之前金额
            BigDecimal oldPrice;
            //记录类型
            int recordType;

            //获取用户信息
            User user = userBaseMapper.selectByPrimaryKey(id);
            if (user == null) {
                throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_YHBCZ, "用户不存在", "userRechargeMoney");
            }
            if (money.compareTo(BigDecimal.ZERO) == 0) {
                throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_QSRZQDJE, "请输入正确的金额");
            }

            boolean isRechaarge = true;
            String text = "系统%s";
            if (money.compareTo(BigDecimal.ZERO) > 0) {
                text = String.format(text, "充值" + money);
            } else {
                isRechaarge = false;
                text = String.format(text, "扣除" + money);
            }
            //1=余额 2=消费金额 3=积分
            switch (type) {
                case 1:
                    if (isRechaarge) {
                        //系统充值
                        recordType = RecordModel.RecordType.SYSTEM_RECHARGE;
                    } else {
                        //系统扣款
                        recordType = RecordModel.RecordType.SYSTEM_DEDUCTION;
                        BigDecimal amt = user.getMoney().add(money);
                        if (user.getMoney().compareTo(BigDecimal.ZERO) <= 0 || amt.compareTo(BigDecimal.ZERO) < 0) {
                            throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_YHYEBZBNJXKC, "用户余额不足");
                        }
                    }
                    text += "余额";
                    oldPrice = user.getMoney();
                    if (oldPrice.add(money).compareTo(new BigDecimal("9999999999.99")) > 0) {
                        throw new LaiKeAPIException(ErrorCode.BizErrorCode.DATA_ERROR, "用户余额已超过上限");
                    }
                    count = userBaseMapper.rechargeUserPrice(id, money);
                    break;
                case 2:
                    if (isRechaarge) {
                        //系统充值消费金额
                        recordType = RecordModel.RecordType.SYSTEM_CONSUMPTION_FUND;
                    } else {
                        //系统扣
                        recordType = RecordModel.RecordType.SYSTEM_BUCKLE_CONSUMPTION;
                        BigDecimal amt = user.getConsumer_money().add(money);
                        if (user.getConsumer_money().compareTo(BigDecimal.ZERO) <= 0 || amt.compareTo(BigDecimal.ZERO) < 0) {
                            throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_YHXFJFBZBNJXKC, "用户消费积分不足,不能进行扣除");
                        }
                    }
                    text += "消费金额";
                    oldPrice = user.getConsumer_money();
                    count = userBaseMapper.rechargeUserByConsumerMoney(id, money);
                    break;
                case 3:
                    //记录积分
                    AddScoreVo addScoreVo = new AddScoreVo();
                    addScoreVo.setOrderNo("");
                    addScoreVo.setUserId(user.getUser_id());
                    addScoreVo.setStoreId(storeId);
                    addScoreVo.setScoreOld(user.getScore());
                    //记录积分
                    String event = String.format("系统充值%s积分", money);
                    if (isRechaarge) {
                        //系统充值积分
                        recordType = RecordModel.RecordType.SYSTEM_RECHARGE_INTEGRAL;
                        addScoreVo.setType(SignRecordModel.ScoreType.SYSTEM_RECHARGE);
                    } else {
                        //系统扣
                        event = String.format("系统扣除%s积分", money);
                        recordType = RecordModel.RecordType.SYSTEM_BUCKLE_INTEGRAL;
                        addScoreVo.setType(SignRecordModel.ScoreType.SYSTEM_DIFF);
                        int amt = user.getScore() + money.intValue();
                        if (user.getScore() <= 0 || amt < 0) {
                            throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_YHJFBZBNJXKC, "用户积分不足,不能进行扣除");
                        }
                    }
                    addScoreVo.setEvent(event);
                    addScoreVo.setScore(money.abs().intValue());
                    publicIntegralService.addScore(addScoreVo);
                    text += "积分";
                    oldPrice = new BigDecimal(String.valueOf(user.getScore()));
                    count = userBaseMapper.rechargeUserByScore(id, money);
                    break;
                default:
                    throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_CSCW, "参数错误", "userRechargeMoney");
            }
            if (count < 1) {
                throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_CZSB, "操作失败", "userRechargeMoney");
            }
            //添加充值记录
            RecordModel recordModel = new RecordModel(storeId, user.getUser_id(), money, oldPrice, new Date(), text, recordType);
            recordModelMapper.insertSelective(recordModel);
            RedisDataTool.refreshRedisUserCache(userBaseMapper.selectByPrimaryKey(user.getId()), redisUtil);

            return true;
        } catch (LaiKeAPIException l) {
            throw l;
        } catch (Exception e) {
            logger.error("会员 充值/消费 异常", e);
            throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_WLYC, "网络异常", "userRechargeMoney");
        }
    }

    @Autowired
    private UserBaseMapper userBaseMapper;

    @Autowired
    private RecordModelMapper recordModelMapper;
}

